package tiled.mapeditor.widget;

import java.awt.Component;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;

import tiled.core.*;
import tiled.mapeditor.MapEditor;
import tiled.mapeditor.brush.CustomBrush;
import tiled.mapeditor.util.TileRegionSelectionEvent;
import tiled.mapeditor.util.TileSelectionEvent;
import tiled.mapeditor.util.TileSelectionListener;

public class TabbedTilesetsPane extends JTabbedPane implements TileSelectionListener
{
    private final HashMap<TileSet, TilePalettePanel> tilePanels =
            new HashMap<TileSet, TilePalettePanel>();
    private final MyChangeListener listener = new MyChangeListener();
    private final MapEditor mapEditor;
    private Map map;

    public TabbedTilesetsPane(MapEditor mapEditor)
    {
        this.mapEditor = mapEditor;
    }

    public void setMap(Map map)
    {
        if (this.map != null)
        {
            this.map.removeMapChangeListener(listener);
        }

        if (map == null)
        {
            removeAll();
        }
        else
        {
            recreateTabs(map.getTilesets());
            map.addMapChangeListener(listener);
        }

        this.map = map;
    }

    private void recreateTabs(List<TileSet> tilesets)
    {
        for (TilePalettePanel panel : tilePanels.values())
        {
            panel.removeTileSelectionListener(this);
            panel.getTileset().removeTilesetChangeListener(listener);
        }
        tilePanels.clear();

        removeAll();

        if (tilesets != null)
        {
             for (TileSet tileSet : tilesets)
             {
                 if (tileSet != null)
                 {
                     addTabForTileSet(tileset);
                 }
             }
        }
    }

    private void addTabForTileset(TileSet tileset)
    {
        tileset.addTilesetChangeListener(listener);
        TilePalettePanel tilePanel = new TilePalettePanel();
        tilePanel.setTileset(tileset);
        tilePanel.addTileSelectionListener(this);
        JScrollPane paletteScrollPane = new JScrollPane(tilePanel,
                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        addTab(tileset.getName(), paletteScrollPane);
        tilePanels.put(tileset, tilePanel);
    }

    public void tileSelected(TileSelectionEvent e)
    {
        mapEditor.setCurrentTile(e.getTile());
    }

    public void tileRegionSelected(TileRegionSelectionEvent e)
    {
        mapEditor.setBrush(new CustomBrush(e.getTileRegion()));
    }

    private class MyChangeListener implements MapChangeListener, TilesetChangeListener
    {
        public void mapChanged(MapChangedEvent e)
        {
        }

        public void tilesetAdded(MapChangedEvent e, Tileset tileset)
        {
            addTabForTileset(tileset);
        }

        public void tilesetRemoved(MapChangedEvent e, int index)
        {
            JScrollPane scroll = (JScrollPane)getComponentAt(index);
            TilePalettePanel panel = (TilePalettePanel)scroll.getViewport().getView();
            TileSet set = panel.getTileset();
            panel.removeTileSelectionListener(TabbedTilesetsPane.this);
            set.removeTilesetChangeListener(listener);
            tilePanels.remove(set);
            removeTabAt(index);
        }

        public void tilesetSwapped(MapChangedEvent e, int index0, int index1)
        {
            int sIndex = getSelectedIndex();

            String title0 = getTileAt(index0);
            String title1 = getTileAt(index1);

            Component comp0 = getComponentAt(index0);
            Component comp1 = getComponentAt(index1);

            removeTabAt(index1);
            removeTabAt(index0);

            insertTab(title1, null, comp1, null, index0);
            insertTab(title1, null, comp0, null, index1);

            if (sIndex == index0)
            {
                sIndex = index1;
            }
            else if (sIndex == index1)
            {
                sIndex = index0;
            }

            setSelectedIndex(sIndex);
        }

        public void tilesetChanged(TilesetChangedEvent event)
        {
        }

        public void nameChanged(TilesetChangedEvent event, String oldName, String newName)
        {
            TileSet set = event.getTileset();
            int index = map.getTilesets().indexOf(set);

            setTileAt(index, newName);
        }

        public void sourceChanged(TilesetChangedEvent event, String oldSource, String newSource)
        {
        }
    }
} 
